// 版权归GoFrame作者(https://goframe.org)所有。保留所有权利。
//
// 本源代码形式受MIT许可证条款约束。
// 如果未随本文件一同分发MIT许可证副本，
// 您可以在https://github.com/gogf/gf处获取。
// md5:a9832f33b234e3f3

package 工具类

import (
	"reflect"

	gconv "gitee.com/go_888/goframe/util/gconv"
)

// X数组浅拷贝 对于最常用的切片类型（[]interface{}）执行浅拷贝操作。
// md5:d119afb140e8324a
func X数组浅拷贝(数组 []interface{}) []interface{} {
	newSlice := make([]interface{}, len(数组))
	copy(newSlice, 数组)
	return newSlice
}

// X数组插入前面 将 `values` 插入到 `index` 位置的前面，并返回一个新的切片。 md5:d1cbe1d61df82fb6
func X数组插入前面(数组 []interface{}, 索引 int, 值s ...interface{}) (新数组 []interface{}) {
	if 索引 < 0 || 索引 >= len(数组) {
		return 数组
	}
	新数组 = make([]interface{}, len(数组)+len(值s))
	copy(新数组, 数组[0:索引])
	copy(新数组[索引:], 值s)
	copy(新数组[索引+len(值s):], 数组[索引:])
	return
}

// X数组插入后面 在 `index` 后方插入 `values`，并返回一个新的切片。 md5:bb561266d0b2b921
func X数组插入后面(数组 []interface{}, 索引 int, 值s ...interface{}) (新数组 []interface{}) {
	if 索引 < 0 || 索引 >= len(数组) {
		return 数组
	}
	新数组 = make([]interface{}, len(数组)+len(值s))
	copy(新数组, 数组[0:索引+1])
	copy(新数组[索引+1:], 值s)
	copy(新数组[索引+1+len(值s):], 数组[索引+1:])
	return
}

// X数组删除成员 从索引 `index` 处删除一个元素，并返回新的切片。如果给定的 `index` 不有效，它不会做任何操作。
// md5:f57a8afe207e8169
func X数组删除成员(数组 []interface{}, 索引 int) (新数组 []interface{}) {
	if 索引 < 0 || 索引 >= len(数组) {
		return 数组
	}
				// 在删除时确定数组边界，以提高删除效率。 md5:bc969ee880edf699
	if 索引 == 0 {
		return 数组[1:]
	} else if 索引 == len(数组)-1 {
		return 数组[:索引]
	}
	// 如果是一个非边界删除，
	// 它将涉及创建一个数组，
	// 那么删除操作效率较低。
	// md5:6a664196d66bc968
	return append(数组[:索引], 数组[索引+1:]...)
}

// X数组到Map 将切片类型变量 `slice` 转换为 `map[string]interface{}` 类型。注意，如果 `slice` 的长度不是偶数，它将返回nil。
// 例如：
// ["K1", "v1", "K2", "v2"] => {"K1": "v1", "K2": "v2"}
// ["K1", "v1", "K2"]       => nil
// md5:f7b4384607d6bfbe
func X数组到Map(数组 interface{}) map[string]interface{} {
	var (
		reflectValue = reflect.ValueOf(数组)
		reflectKind  = reflectValue.Kind()
	)
	for reflectKind == reflect.Ptr {
		reflectValue = reflectValue.Elem()
		reflectKind = reflectValue.Kind()
	}
	switch reflectKind {
	case reflect.Slice, reflect.Array:
		length := reflectValue.Len()
		if length%2 != 0 {
			return nil
		}
		data := make(map[string]interface{})
		for i := 0; i < reflectValue.Len(); i += 2 {
			data[gconv.String(reflectValue.Index(i).Interface())] = reflectValue.Index(i + 1).Interface()
		}
		return data
	}
	return nil
}

// X数组到Map并按指定名称 将切片类型变量 `slice` 转换为 `map[interface{}]interface{}`
// 切片中指定列的值将作为返回映射的键。
// 例如：
// X数组到Map并按指定名称([{"K1": "v1", "K2": 1}, {"K1": "v2", "K2": 2}], "K1") => {"v1": {"K1": "v1", "K2": 1}, "v2": {"K1": "v2", "K2": 2}}
// X数组到Map并按指定名称([{"K1": "v1", "K2": 1}, {"K1": "v2", "K2": 2}], "K2") => {1: {"K1": "v1", "K2": 1}, 2: {"K1": "v2", "K2": 2}}
// md5:bf178f79b93bd1b2
func X数组到Map并按指定名称(数组 interface{}, 名称 interface{}) map[interface{}]interface{} {
	var (
		reflectValue = reflect.ValueOf(数组)
		reflectKind  = reflectValue.Kind()
	)
	for reflectKind == reflect.Ptr {
		reflectValue = reflectValue.Elem()
		reflectKind = reflectValue.Kind()
	}
	data := make(map[interface{}]interface{})
	switch reflectKind {
	case reflect.Slice, reflect.Array:
		for i := 0; i < reflectValue.Len(); i++ {
			if k, ok := ItemValue(reflectValue.Index(i), 名称); ok {
				data[k] = reflectValue.Index(i).Interface()
			}
		}
	}
	return data
}
